package com.suxin.ratelimit.v2.handler;

import com.suxin.ratelimit.v2.RateLimit;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @author Tang
 * @classname RateLimitHandler
 * @description [  ]
 * @date 2022/2/10 9:32
 */
public interface RateLimitHandler {

    class RateLimitConstKey {

        final static String LUA_LIMIT = "local key = KEYS[1] \n" +
                "local limit = tonumber(ARGV[1]) \n" +
                "local time = ARGV[2] \n" +
                "local current = tonumber(redis.call('get', key) or \"0\")\n" +
                "if current + 1 > limit\n" +
                "then \n" +
                "    return 0\n" +
                "else \n" +
                "    redis.call(\"INCRBY\", key,\"1\")\n" +
                "    redis.call(\"expire\", key,time)\n" +
                "    return current + 1\n" +
                "end";

        final static String LIMIT_KEY = "LIMIT_KEY";

    }

    /**
     * handler
     *
     * @param rate
     * @return x
     */
    default boolean handler(Rate rate) {
        RateLimit.TYPE rateType = rate.getType();
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        String key = "";
        switch (rateType) {
            case URL:
                key = request.getRequestURI();
                break;
            case IP:
                key = request.getRemoteAddr();
                break;
            default:
                break;
        }
        return doHandler(rate, key);
    }

    /**
     * doHandler
     *
     * @param rate
     * @param key
     * @return x
     */
    boolean doHandler(Rate rate, String key);


}
